package edu.pku.sei.transformation.editor.controller.policies;

import org.eclipse.draw2d.geometry.Rectangle;
import org.eclipse.gef.EditPart;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CompoundCommand;
import org.eclipse.gef.requests.CreateRequest;

import edu.pku.sei.modeler.commands.ChangeConstraintCommand;
import edu.pku.sei.modeler.exceptions.FactoryNotFoundException;
import edu.pku.sei.modeler.model.common.AbstractFactory;
import edu.pku.sei.modeler.model.common.ModelRegistry;
import edu.pku.sei.modeler.model.structure.MetaDiagram;
import edu.pku.sei.modeler.model.structure.MetaLink;
import edu.pku.sei.modeler.model.structure.MetaNode;
import edu.pku.sei.modeler.model.structure.StructureFactory;
import edu.pku.sei.transformation.editor.binding.BindingRecorder;
import edu.pku.sei.transformation.editor.controller.commands.CommandFactory;
import edu.pku.sei.transformation.editor.controller.commands.link.LinkCreateCommand;
import edu.pku.sei.transformation.editor.controller.editparts.node.GraphicalDomainEditpart;
import edu.pku.sei.transformation.editor.model.Domain;
import edu.pku.sei.transformation.editor.model.DomainConnection;
import edu.pku.sei.transformation.editor.model.GraphicalDomain;
import edu.pku.sei.transformation.editor.model.ModelPackage;

public class RuleDiagramLayoutEditPolicy extends
		TransformationEditorXYLayoutPolicy {

	@Override
	protected Command getCreateCommand(CreateRequest request) {
		if (request.getNewObject() instanceof MetaNode
				&& ((MetaNode) request.getNewObject()).getModelElement() instanceof Domain) {
			MetaNode node = (MetaNode) request.getNewObject();
			MetaDiagram diagram = (MetaDiagram) getHost().getModel();
			Rectangle constraint = (Rectangle) getConstraintFor(request);

			Command cmd = CommandFactory.getCreateCommand(node, diagram,
					constraint);
			LinkCreateCommand linkCmd = null;

			try {
				AbstractFactory factory = ModelRegistry.getRegistry()
						.getFactory(node.getModel());
				StructureFactory sfactory = (StructureFactory) ModelRegistry
						.getRegistry().getStructureFactory(node.getModel());
				DomainConnection rc = (DomainConnection) factory.createElement(
						ModelPackage.__DOMAIN_CONNECTION__, true);
				MetaLink link = sfactory.createMetaLink();
				link.setModelElement(rc);

				MetaNode relationNode = BindingRecorder
						.getRelationNodeByDiagram(diagram);
				linkCmd = CommandFactory.getCreateCommand(link, relationNode);
				linkCmd = CommandFactory.completeCreateCommand(linkCmd, node);

			} catch (IllegalArgumentException e) {
				e.printStackTrace();
			} catch (FactoryNotFoundException e) {
				e.printStackTrace();
			}

			CompoundCommand compoundCmd = new CompoundCommand();
			compoundCmd.add(cmd);
			compoundCmd.add(linkCmd);
			return compoundCmd;
		}
		return null;
	}

	@Override
	protected Command createChangeConstraintCommand(EditPart child,
			Object constraint) {
		Rectangle bounds = (Rectangle) constraint;
		MetaNode node = (MetaNode) child.getModel();
		if (child instanceof GraphicalDomainEditpart
				&& ((GraphicalDomain) node.getModelElement()).isCollapsed()) {
			return new ChangeConstraintCommand(node, bounds.getLocation(), node
					.getWidth(), node.getHeight());
		} else {
			return new ChangeConstraintCommand(node, bounds.getLocation(),
					bounds.width, bounds.height);
		}
	}
}
